// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

Cypress.Commands.add("login", () => {
    cy.visit("/user/login")
    cy.get("#username").focus().clear().type(Cypress.env("SYSOM_ACCOUNT_USERNAME"))
    cy.get("#password").focus().clear().type(Cypress.env("SYSOM_ACCOUNT_PASSWORD"))
    cy.get("button").contains("登录").click()
    cy.get("button").contains("忽 略").click()
})

/**
 * SysOM 诊断测试封装
 * @param {*} pageUrl               诊断前端url
 * @param {*} params                诊断参数
 * @param {*} resultCheckCallback   诊断结果处理（在此处判断诊断结果是否符合预期）
 */
Cypress.Commands.add("sysomDiagnosisCheck", (pageUrl, params, resultCheckCallback) => {
    cy.intercept("POST", "/api/v1/tasks/")
        .as("createDiagnosisTask")

    cy.intercept("GET", "/api/v1/tasks/?*")
        .as("getDiagnosisTasks")

    cy.intercept("GET", "/api/v1/tasks/*/")
        .as("getTaskDetail")

    // 1. 访问自定义诊断页面
    cy.visit(pageUrl)

    // 2 输入instance参数
    for (let k in params) {
        if (k.indexOf("instance") != -1) {
            cy.get(`#${k}`).parent().parent().click()
            cy.get(".rc-virtual-list-holder-inner").contains(params[k]).click()
        } else {
            cy.get(`#${k}`).invoke("attr", "readonly").then(res => {
                if (!!res) {
                    // readonly options
                    cy.get(`#${k}`).parent().parent().click()
                    cy.get(".rc-virtual-list-holder-inner").contains(params[k]).click()
                } else {
                    cy.get(`#${k}`).focus().clear().type(params[k], { force: true })
                }
            })
        }
    }

    // 3 点击开始诊断按钮发起诊断
    cy.get("button").contains("开始诊断").click()

    ///////////////////////////////////////////////////////////////////////////////////////
    // 结果判断
    ///////////////////////////////////////////////////////////////////////////////////////

    const getAndCheckTaskResult = (task_id) => {
        // 点击一下刷新按钮
        cy.get('span[aria-label="reload"]').click()
        cy.wait("@getDiagnosisTasks").its("response.statusCode").should("eq", 200)
        cy.wait(100)
        cy.get("td")
            .contains(task_id)
            .parent()
            .parent()
            .then($el => {
                let current_text = $el.text()
                if (current_text.indexOf("暂无可用操作") != -1) {
                    // 诊断运行中，等待十秒后再次检查
                    cy.wait(5000)
                    getAndCheckTaskResult(task_id)
                } else {
                    if (current_text.indexOf("查看诊断结果") != -1) {
                        // 诊断已经正常结束
                        cy.wrap($el).find("td").contains("查看诊断结果").click()
                    } else {
                        // 诊断已经异常结束
                        cy.wrap($el).find("td").contains("查看出错信息").click()
                    }
                    cy.wait("@getTaskDetail").then(interception => {
                        expect(interception).to.have.property('response')
                        expect(interception.response?.body.code, 'code').to.equal(200)
                        expect(interception.response.statusCode).to.equal(200)
                        // 执行回调函数
                        resultCheckCallback && resultCheckCallback(interception.response.body.data)
                    })
                }
            })
    }

    cy.wait('@createDiagnosisTask')
        .then((interception) => {
            expect(interception).to.have.property('response')
            expect(interception.response?.body.code, 'code').to.equal(200)
            expect(interception.response.statusCode).to.equal(200)
            expect(interception.response.body.data).to.have.property("task_id")

            // 得到诊断 ID
            let task_id = interception.response?.body.data.task_id

            // 轮询获取诊断结果
            getAndCheckTaskResult(task_id)
        })
});

Cypress.Commands.add("getIframeBody", (iframe_selector = "iframe") => {
    cy.get(iframe_selector)
        // Cypress yields jQuery element, which has the real
        // DOM element under property "0".
        // From the real DOM iframe element we can get
        // the "document" element, it is stored in "contentDocument" property
        // Cypress "its" command can access deep properties using dot notation
        // https://on.cypress.io/its
        .its('0.contentDocument')
        .should('exist')
        // automatically retries until body is loaded
        .its('body').should('not.be.undefined')
        // wraps "body" DOM element to allow
        // chaining more Cypress commands, like ".find(...)"
        // https://on.cypress.io/wrap
        .then((body) => cy.wrap(body, { log: false }))
});

Cypress.Commands.add("getPannelByTitle", (title) => {
    return cy.getIframeBody()
        .find("div.react-grid-layout")
        .find("div.react-grid-item")
        .find("div.panel-header")
        .filter((_, element) => {
            return Cypress.$(element).text().trim() == title
        })
        .parents("div.react-grid-item")
});

Cypress.Commands.add("getPannelHeaderByTitle", (title) => {
    return cy.getPannelByTitle(title).find("div.panel-header")
});

Cypress.Commands.add("getPannelContentByTitle", (title) => {
    return cy.getPannelByTitle(title).find("div.panel-content").scrollIntoView();
});

/**
 * SysOM 日志模块测试封装
 * @param {*} pageUrl 页面地址
 * @param {*} params  列表过滤参数
 * @param {*} resultCallback 结果回调, 返回结果是否达到预期
 */
Cypress.Commands.add("sysomLogSelectOrFilter", (pageUrl, params, isSelect) => {
    // 1. 跳转到自定义log页面
    cy.visit(pageUrl)

    // 2. 等待页面加载完成
    cy.wait(2000)

    // 3. 查找filter展开按钮并点击，若没有则跳过
    if (isSelect) {
        const el_show = 'a[class="ant-pro-form-collapse-button"]'
        cy.get(el_show).contains("展开").click()
    }

    // 4. 输入查询参数
    for (let param in params) {
        cy.get(`input[id=${param}]`).focus().type(params[param], {force: true})
    }

    // 5. 点击查询按钮
    cy.get(':nth-child(2) > .ant-btn > span').click()

    // 6. table 内容断言
    cy.get('.ant-table-tbody').find('tr').should("have.length.gte", 1)
    
})

/**
 * 打开闭合的主标签
 * @param {*} title panel tag
 */
Cypress.Commands.add("openMainLabel", (title) => {
    cy.getIframeBody()
        .find("div.react-grid-layout")
        .find("div.react-grid-item")
        .find("a")
            .contains(title).click()
})

/* 
* 面板数值大于等于 0
* @param {*} title panel tag
*/
Cypress.Commands.add("panelNumericalValueGteTest", (title) => {
    cy.getPannelContentByTitle(title).contains(/\d+/).then(($el) => {
        const num = parseInt($el.text());
        expect(num).to.be.gte(0);
    })
})

/**
 * 面板取a便签数 大于等于 0
 * @param {*} title panel tag
 */

Cypress.Commands.add("panelAtagValueGteTest", (title) => {
    cy.getPannelContentByTitle(title).find("a").should("have.length.gte", 0)
})

/**
 * 面板取a便签数 大于等于 0, 无数据时显示No data
 * @param {*} title panel tag
 */
Cypress.Commands.add("panelAtagValueGteOrNoDataTest", (title) => {
    cy.getPannelContentByTitle(title)
        .then(($el) => {
            if ($el.text().includes("No data")) {
                cy.wrap($el).contains("No data");
            } else {
                cy.wrap($el).find("a").should("have.length.gte", 0)
            }
        })
})

/**
 *  面板取折线统计图且具有Table
 *  @params {*} title panel tag
 *  @items {*} items 属性名称 列表
 */
Cypress.Commands.add("panelFoldLineTableGteTest", (title, Array) => {
    cy.getPannelContentByTitle(title).find("tbody tr").should("have.length.gt", 0)
    if (Array !== undefined) {
            Array.forEach((item, index) => {
            cy.getPannelContentByTitle(title).find("tbody tr").eq(index).find("td").eq(0).contains(item)
        })
    }
})

Cypress.Commands.add("panelNoDataTest", (title) => {
    cy.getPannelContentByTitle(title).then(($el) => {
        console.log($el.text())
        if ($el.text().includes("No data")) {
            cy.wrap($el).contains("No data");
        } else {
            cy.getPannelContentByTitle(title).find("canvas").should('be.empty')
        }
    })
})

Cypress.Commands.add("diagnosisTaskResultHandler", (result, callback) => {
    if (result.status === "Success") {
        callback && callback()
    } else {
        cy.get('.ant-modal-confirm-title').should("include.text", "诊断失败")
        cy.get("button").should("include.text", "OK")
        cy.get("button").contains("OK").click()
    }
})
